package com.onec.service.manage.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.crypto.digest.DigestUtil;
import com.onec.service.api.annotation.RestfulControllerLog;
import com.onec.service.api.content.RedisKeyContent;
import com.onec.service.api.dto.response.BaseResponse;
import com.onec.service.api.enums.ResultCodeEnum;
import com.onec.service.api.utils.IPUtil;
import com.onec.service.api.utils.RedisKeyUtil;
import com.onec.service.api.utils.ValidatorUtils;
import com.onec.service.api.utils.group.manage.Login;
import com.onec.service.api.utils.group.manage.Register;
import com.onec.service.manage.component.WhiteUrl;
import com.onec.service.manage.content.TokenContent;
import com.onec.service.manage.dto.req.UserInfoReq;
import com.onec.service.manage.dto.resp.UserInfoResp;
import com.onec.service.manage.entity.UserInfo;
import com.onec.service.manage.utils.JwtUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * @author ONEC
 * @since 2018-10-22
 */
@Slf4j
@ApiOperation(value = "管理登录界面")
@RestController
public class LoginController extends BaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);

    @Autowired
    private WhiteUrl whiteUrl;


    /**
     * 验证登陆页面
     *
     * @return
     */
    @RestfulControllerLog(name = "管理平台用户登录")
    @RequestMapping(value = "/toLogin", method = RequestMethod.POST)
    public BaseResponse loginManage(@RequestBody UserInfoReq userInfoDto, HttpServletRequest request) {

        ValidatorUtils.validateEntity(userInfoDto, Login.class);
        UserInfo userInfo = userLoginService.findUserName(userInfoDto.getUserName());
        if (Optional.ofNullable(userInfo).isEmpty()) {
            return BaseResponse.error(ResultCodeEnum.USERNAME_OR_PASSWORD_ERROR);
        }
        ByteSource byteSource = ByteSource.Util.bytes(userInfo.getSalt());
        String password = new SimpleHash("MD5", userInfoDto.getPassword(), byteSource, 1024).toHex();
        if (Objects.equals(userInfo.getPassword(), password)) {
            String sign = JwtUtil.sign(userInfoDto.getUserName(), userInfo.getSalt(), userInfo.getId());
            // 注意此处的proCode ：与登出（loginout） shiroreal 认证的proCode 必须一致：
            String proCode = request.getRemoteAddr() + "_" + userInfo.getId();
            String loginKey = RedisKeyUtil
                    .getKey(RedisKeyContent.SERVICE_MANAGE, RedisKeyContent.SERVICE_MANAGE_LOGIN, proCode);
            stringRedisTemplate.opsForValue()
                    .set(loginKey, DigestUtil.md5Hex(sign + userInfo.getSalt()), TokenContent.TOKEN_EXPIRE_HOURS, TimeUnit.HOURS);
            return new UserInfoResp(ResultCodeEnum.SUCCESS, sign, userInfo.getUserName(),
                    DateUtil.offsetHour(DateUtil.date(), TokenContent.TOKEN_EXPIRE_HOURS.intValue()));
        }
        return BaseResponse.error(ResultCodeEnum.USERNAME_OR_PASSWORD_ERROR);
    }

    /**
     * 验证登陆页面
     *
     * @return
     */
    //@RequiresRoles("ADMIN")
    @RestfulControllerLog(name = "新增管理人员")
    @RequestMapping(value = "/register", method = RequestMethod.POST, produces = {"application/json; charset=UTF-8"})
    public BaseResponse register(@RequestBody UserInfoReq userInfoDto) {

        ValidatorUtils.validateEntity(userInfoDto, Register.class);
        userLoginService.saveUserInfo(userInfoDto);
        return UserInfoResp.error(ResultCodeEnum.SUCCESS);
    }

    /**
     * shiro 登出操作
     *
     * @return
     */
    @RestfulControllerLog(name = "用户登出操作")
    @RequestMapping(value = "/logout")
    public BaseResponse logout(HttpServletRequest httpRequest) {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        String token = httpRequest.getHeader(TokenContent.TOKEN);
        Long userId = JwtUtil.getUserId(token);
        String proCode = IPUtil.getIpAddr(httpRequest) + "_" + userId;
        String loginKey = RedisKeyUtil
                .getKey(RedisKeyContent.SERVICE_MANAGE, RedisKeyContent.SERVICE_MANAGE_LOGIN, proCode);
        stringRedisTemplate.delete(loginKey);
        return BaseResponse.ok();
    }


    /**
     * 添加运营管理人员（当前权限为：admin）
     *
     * @param request
     * @return
     */
    @RequestMapping(value = "addOperation")
    @RequiresPermissions("PN0001")
    public boolean addOperation(HttpServletRequest request) {
        log.info("测试权限问题！");
        return true;
    }


}
